package com.tiancheng.trade.commom.core.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class MD5Utils {

    private static String key = "kmnt192006250b4c09247ec02edce69f6a2d";

    /**
     * MD5加密
     *
     * @param input
     * @return
     */
    public static String getMD5Content(String input) {
        try {
            // 拿到MD转换器
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");

            byte[] inputByteArray = input.getBytes();
            messageDigest.update(inputByteArray);

            byte[] resultByteArray = messageDigest.digest();

            return byteArrayToHex(resultByteArray);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将字节数组转换成16进组的字符串
     *
     * @param byteArray
     * @return
     */
    public static String byteArrayToHex(byte[] byteArray) {
        // 初始化一个字符数组，用来存放每个16进制字符
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

        char[] resultCharArray = new char[byteArray.length * 2];

        int index = 0;
        // 遍历字节数组，通过位运算，转换成字符放到字符数据中
        for (byte b : byteArray) {
            resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
            resultCharArray[index++] = hexDigits[b & 0xf];
        }

        return new String(resultCharArray);
    }


    /**
     * 根据参数获取签名
     *
     * @param timeStamp
     * @param params
     * @return
     */
    public static String createSign(String timeStamp, SortedMap<String, Object> params) {
        String plain = generateSignPlain(params).toString();
        String md5value = plain + "&key=" + key;
        //排序后的参数MD5加密
        String sign = MD5Util.MD5Encode(md5value, "UTF-8");
        sign = sign + timeStamp;
        sign = MD5Util.MD5Encode(sign, "UTF-8");
        return sign;
    }

    /**
     * 按照key值字典顺序，并用&拼接
     *
     * @param params
     * @return
     */
    private static StringBuilder generateSignPlain(SortedMap<String, Object> params) {
        StringBuilder plain = new StringBuilder();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if (entry.getValue() instanceof List) {
                List<Map<String, Object>> list = (List<Map<String, Object>>) entry.getValue();
                if (list != null && list.size() > 0) {
                    plain.append(entry.getKey() + "=[");
                    for (int i = 0; i < list.size(); i++) {
                        plain.append("{").append(generateSignPlain(new TreeMap<>(list.get(i))));
                        plain.append(i == list.size() - 1 ? "}" : "}&");
                    }
                    plain.append("]&");
                }
            } else if (entry.getValue() instanceof Map) {
                Map<String, Object> map = (Map<String, Object>) entry.getValue();
                if (map != null && map.size() > 0) {
                    plain.append(entry.getKey() + "=").append("{").append(generateSignPlain(new TreeMap<>(map))).append("}&");
                }
            } else {
                plain.append(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        return plain.length() > 0 ? plain.deleteCharAt(plain.length() - 1) : new StringBuilder();
    }
}
